package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;

import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import xmlEntities.FacturaXML;
import xmlEntities.ItemXML;
import xmlEntities.SolicitudCompraXML;

import ejbs.Facade;
import entities.*;

public class homeServlet extends HttpServlet {
	
	private final long serialVersionUID = 1L;

	public homeServlet() {
		super();
		
	}

	protected void doGet(HttpServletRequest request,
		HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println(" <head>");
		out.println("  <title>Pruebas del servlet</title>");
		out.println(" </head>");
		out.println(" <body>");
		out.println("  <h1>Tp Taller</h1>");
		
		
		
		try {
			//probarApplicationServer(new PrintWriter(System.out));
			probarApplicationServer(out);
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		out.println(" </body>");
		out.println("</html>");
		
		String url="/Menu.jsp";
	    ServletContext sc = getServletContext();
	    RequestDispatcher rd = sc.getRequestDispatcher(url);
	    rd.forward(request,response);
	}

	protected void mostrarLinea(PrintWriter out, String s){
		out.println("<br>" + s);
	}
	
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		

	}

	public void probarApplicationServer(PrintWriter out) throws NamingException {

		String naming = "TPEAR/FacadeBean/remote";
		Hashtable props = new Hashtable();
		props.put(InitialContext.INITIAL_CONTEXT_FACTORY,
				"org.jnp.interfaces.NamingContextFactory");
		props.put(InitialContext.PROVIDER_URL, "jnp://127.0.0.1:1099");
		InitialContext ic = new InitialContext(props);
		Facade f = (Facade) ic.lookup(naming);
		

		// 0 - Crear algunos productos
		crearProductosDePrueba(f, out);
		pruebaObtenerProducto(f, out);

		// 1 - Solicitar Cotizacion (sincronico)
		pruebaSolicitarCotizacion(f, out);
		pruebaObtenerSolicitudesDeCotizacion(f, out);
		pruebaObtenerCotizaciones(f, out);

		// 2 - Generar Solicitud de Compra
		pruebaSolicitarCompra(f, out);
		pruebaObtenerSolicitudesDeCompra(f, out);

		// 3 - Recibir Factura (asincronico)
		pruebaObtenerFacturasRecibidas(f, out);

		// 4 - Recibir Datos de Producto
		pruebaObtenerDatosRecibidos(f);
		
		// 5 - Prueba Enviar Facturda Desde Oficina de Venta
		try {
			pruebaEnviarFacturaDesdeOficinaDeVenta(f);
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void crearProductosDePrueba(Facade f, PrintWriter out) {

		ArrayList<Producto> articulos = f.obtenerArticulos();
		if (articulos.size() == 0) {
			f.crearArticulo("A1", "caract A1", "marca A1", "origen A1", "desc A1");
			f.crearArticulo("A2", "caract A2", "marca A2", "origen A2", "desc A2");
			f.crearArticulo("A3", "caract A3", "marca A3", "origen A3", "desc A3");
			f.crearArticulo("A4", "caract A4", "marca A4", "origen A4", "desc A4");
			f.crearArticulo("A5", "caract A5", "marca A5", "origen A5", "desc A5");
		}

		articulos = f.obtenerArticulos();
		System.out.println(f.obtenerArticulo("A1"));

		mostrarLinea(out, "Productos creados:");
		for (int i = 0; i < articulos.size(); i++) {
			Producto a = articulos.get(i);
			mostrarArticulo(a, out);
		}
		mostrarSeparador(out);
	}

	private void mostrarArticulo(Producto a, PrintWriter out) {
		mostrarLinea(out, a.getCodigo() + " " + a.getCaracteristica() + " "
				+ a.getMarca() + " " + a.getOrigen());
	}

	private void mostrarSolicitudCotizacion(
			SolicitudCotizacion solicitudCotizacion, PrintWriter out) {
		mostrarLinea(out, "Solicitud Cotizacion id: "
				+ solicitudCotizacion.getId() + " items: "
				+ solicitudCotizacion.getItemsACotizar().size());
		Iterator<ItemACotizar> itr = solicitudCotizacion.getItemsACotizar()
				.iterator();
		while (itr.hasNext()) {
			ItemACotizar item = itr.next();
			mostrarLinea(out, "cod: " + item.getCodigo() + " cant: "
					+ item.getCantidad());
		}
	}

	private void mostrarCotizacion(Cotizacion cotizacion, PrintWriter out) {
		mostrarLinea(out, "Cotizacion id: " + cotizacion.getId() + " items: "
				+ cotizacion.getItemsCotizados().size() + " vigencia: "
				+ cotizacion.getVigencia());
		Iterator<ItemCotizado> itr = cotizacion.getItemsCotizados().iterator();
		while (itr.hasNext()) {
			ItemCotizado item = itr.next();
			mostrarLinea(out, "cod: " + item.getCodigo() + " cant: "
					+ item.getCantidad() + " precio: $" + item.getPrecio());
		}
	}

	private void mostrarSolicitudCompra(SolicitudCompra solicitudCompra, PrintWriter out) {
		mostrarLinea(out, "Solicitud Compra id: " + solicitudCompra.getId()
				+ " items: " + solicitudCompra.getItemsAComprar().size());
		Iterator<ItemAComprar> itr = solicitudCompra.getItemsAComprar()
				.iterator();
		while (itr.hasNext()) {
			ItemAComprar item = itr.next();
			mostrarLinea(out, "cod: " + item.getCodigo() + " cant: "
					+ item.getCantidad());
		}
	}

	private void mostrarFactura(Factura factura, PrintWriter out) {
		mostrarLinea(out, "Factura id: " + factura.getId() + " items: "
				+ factura.getItemsFacturados().size() + " fecha: "
				+ factura.getFecha());
		Iterator<ItemFacturado> itr = factura.getItemsFacturados().iterator();
		while (itr.hasNext()) {
			ItemFacturado item = itr.next();
			mostrarLinea(out, "cod: " + item.getCodigo() + " cant: "
					+ item.getCantidad() + " precio: $" + item.getPrecio());
		}
	}

	private void mostrarSeparador(PrintWriter out) {
		mostrarLinea(out, "---------------------------");
		mostrarLinea(out, "");
	}

	private void pruebaObtenerProducto(Facade f, PrintWriter out) {

		mostrarLinea(out, "Obteniendo articulo A3:");
		Producto a = f.obtenerArticulo("A3");
		mostrarArticulo(a, out);
		mostrarSeparador(out);
	}

	private void pruebaSolicitarCotizacion(Facade f, PrintWriter out) {

		mostrarLinea(out, "Solicitando una cotizacion...");
		SolicitudCotizacion solicitudCotizacion = new SolicitudCotizacion();

		ItemACotizar item1 = new ItemACotizar();
		item1.setCodigo("A2");
		item1.setCantidad(5);
		item1.setSolicitudCotizacion(solicitudCotizacion);

		ItemACotizar item2 = new ItemACotizar();
		item2.setCodigo("A4");
		item2.setCantidad(8);
		item2.setSolicitudCotizacion(solicitudCotizacion);

		solicitudCotizacion.getItemsACotizar().add(item1);
		solicitudCotizacion.getItemsACotizar().add(item2);

		f.cotizar(solicitudCotizacion);

		mostrarLinea(out, "Solicitud de cotizacion creada!");

		mostrarSeparador(out);
	}

	private void pruebaObtenerSolicitudesDeCotizacion(Facade f, PrintWriter out) {

		mostrarLinea(out, "Solicitudes de cotizacion creadas:");

		ArrayList<SolicitudCotizacion> solicitudesCotizacion = f
				.obtenerSolicitudesCotizacion();

		Iterator<SolicitudCotizacion> itr = solicitudesCotizacion.iterator();
		while (itr.hasNext()) {
			SolicitudCotizacion solicitudCotizacion = itr.next();
			mostrarSolicitudCotizacion(solicitudCotizacion, out);
			mostrarLinea(out, "   ---   ");
		}
		mostrarSeparador(out);
	}

	private void pruebaObtenerCotizaciones(Facade f, PrintWriter out) {

		mostrarLinea(out, "Cotizacion creadas:");

		ArrayList<Cotizacion> cotizaciones = f.obtenerCotizaciones();

		Iterator<Cotizacion> itr = cotizaciones.iterator();
		while (itr.hasNext()) {
			Cotizacion cotizacion = itr.next();
			mostrarCotizacion(cotizacion, out);
			mostrarLinea(out, "   ---   ");
		}
		mostrarSeparador(out);
	}

	private void pruebaSolicitarCompra(Facade f, PrintWriter out) {

		mostrarLinea(out, "Solicitando una compra...");
		SolicitudCompra solicitudCompra = new SolicitudCompra();

		ItemAComprar item1 = new ItemAComprar();
		item1.setCodigo("A1");
		item1.setCantidad(2);
		item1.setSolicitudCompra(solicitudCompra);
		ItemAComprar item2 = new ItemAComprar();
		item2.setCodigo("A2");
		item2.setCantidad(4);
		item2.setSolicitudCompra(solicitudCompra);
		ItemAComprar item3 = new ItemAComprar();
		item3.setCodigo("A3");
		item3.setCantidad(6);
		item3.setSolicitudCompra(solicitudCompra);

		solicitudCompra.getItemsAComprar().add(item1);
		solicitudCompra.getItemsAComprar().add(item2);
		solicitudCompra.getItemsAComprar().add(item3);

		f.solicitarCompra(solicitudCompra);

		mostrarLinea(out, "Solicitud de compra creada!");

		mostrarSeparador(out);
	}

	private void pruebaObtenerSolicitudesDeCompra(Facade f, PrintWriter out) {

		mostrarLinea(out, "Solicitudes de compra creadas:");

		ArrayList<SolicitudCompra> solicitudesCompra = f
				.obtenerSolicitudesCompra();

		Iterator<SolicitudCompra> itr = solicitudesCompra.iterator();
		while (itr.hasNext()) {
			SolicitudCompra solicitudCompra = itr.next();
			mostrarSolicitudCompra(solicitudCompra, out);
			mostrarLinea(out, "   ---   ");
		}
		mostrarSeparador(out);
	}

	private void pruebaObtenerFacturasRecibidas(Facade f, PrintWriter out) {

		mostrarLinea(out, "Facturas recibidas:");

		ArrayList<Factura> facturas = f.obtenerFacturasRecibidas();

		Iterator<Factura> itr = facturas.iterator();
		while (itr.hasNext()) {
			Factura factura = itr.next();
			mostrarFactura(factura, out);
			mostrarLinea(out, "   ---   ");
		}
		mostrarSeparador(out);

	}

	private void pruebaObtenerDatosRecibidos(Facade f) {

	}
	
	
	private void pruebaEnviarFacturaDesdeOficinaDeVenta(Facade f) throws NamingException, JMSException 
	{
		String xmlAEnviar = "<Factura>"+
							"<numero>3</numero>"+
								"<fechaEmision>20121108</fechaEmision>"+
								"<oficVta>5</oficVta>" +
								"<condicionVenta>condicionDeVenta</condicionVenta>"+
								"<total>10.5</total>"+
								"<subTotal>14.5</subTotal>"+
								"<recargo>5.6</recargo>"+
								"<descuento>12.4</descuento>"+
								"<Items>"+
									"<Item>"+
										"<codigo>A6</codigo>"+
										"<cantidad>6</cantidad>"+
										"<precio>22.7</precio>"+
									"</Item>"+
									"<Item>"+
										"<codigo>A7</codigo>"+
										"<cantidad>8</cantidad>"+
										"<precio>16.22</precio>"+
									"</Item>"+
								"</Items>"+
							"</Factura>";
		
		Hashtable props = new Hashtable();		
		props.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
		
		//Esta direccion va a ser la nuestra y la oficina de venta la va a tener que poner
		String nuestroIP = "jnp://127.0.0.1:1099";		
		
		props.put(InitialContext.PROVIDER_URL, nuestroIP);		
		Context ctx = new InitialContext(props);		
		QueueConnectionFactory qfactory = (QueueConnectionFactory)ctx.lookup("ConnectionFactory");		
		Queue queue = (Queue)ctx.lookup("queue/recibirFacturaQueue");		
		QueueConnection qCon = qfactory.createQueueConnection();
		QueueSession qSession = qCon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);		
		QueueSender qSender = qSession.createSender(queue);				
		TextMessage message = qSession.createTextMessage(xmlAEnviar);		
		qSender.send(message);	
	}

}
